Skip to content

Conversation

@fabianfett
Copy link
Collaborator

OG PR is #600, recreated to ensure correct emails are being used for commits.

Received the following diagnostics while designing an application with postgres-nio 1.27.0...1.29.0:

00:56:35.221 [NotificationsListener.swift:517] - Notifications: Failed to LISTEN {error: "PSQLError(code: server, serverInfo: [sqlState: 57P01, file: be-secure.c, line: 209, message: terminating connection due to unexpected postmaster exit, routine: secure_read, localizedSeverity: FATAL, severity: FATAL])", topic: hawq_39}
00:56:35.222 [PostgresChannelHandler.swift:104] - Channel error caught. {psql_error: "I/O on closed channel", psql_connection_id: "1"}
00:56:35.222 [NotificationsListener.swift:286] - Notifications: Restarting subscription {topic: hawq_205}
00:56:35.222 [NotificationsListener.swift:148] - Notifications: Starting listening {psql.conn.id: "0", psql.conn.isClosed: true, topic: hawq_157}

SWIFT TASK CONTINUATION MISUSE: listen(_:) leaked its continuation without resuming it. This may cause tasks waiting on it to remain suspended forever.

And then the application deadlocks because listen() doesn't ever return.

Reproduction:

  1. The code looks like that:

             try await self.postgresClient.withConnection { connection in
                 148: log.debug("Notifications: Starting listening", metadata: [       
                     "topic": "\(topic)",                                         
                     "psql.conn.id": "\(connection.id)",                          
                     "psql.conn.isClosed": "\(connection.isClosed)"               
                 ])                                                               
                 sequence = try await connection.listen(topic.stringValue)        
                 154: log.debug("Notifications: Now listening", metadata: [            
                     "topic": "\(topic)",                                          
                     "psql.conn.id": "\(connection.id)",                          
                     "psql.conn.isClosed": "\(connection.isClosed)"               
                 ])
    
  2. brew services restart postgresql

  3. The error log similar to the log above gets generated, and the system goes into a deadlock.

Notice the log from line 148 is present, the connection appears to be CLOSED, and then the line 154 is unreachable. This might mean that listen() state machine is not correct on closed channels and result in deadlock.

@fabianfett fabianfett requested a review from gwynne as a code owner December 19, 2025 14:35
@gwynne gwynne added the semver-patch No public API change. label Dec 19, 2025
@fabianfett fabianfett enabled auto-merge (squash) December 19, 2025 14:39
@fabianfett fabianfett merged commit 46b2b3d into vapor:main Dec 19, 2025
9 of 10 checks passed
@codecov
Copy link

codecov bot commented Dec 19, 2025

Codecov Report

❌ Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.40%. Comparing base (89d9f72) to head (108ccc1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
Sources/PostgresNIO/New/NotificationListener.swift 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #616      +/-   ##
==========================================
+ Coverage   76.09%   76.40%   +0.31%     
==========================================
  Files         134      134              
  Lines       10147    10161      +14     
==========================================
+ Hits         7721     7764      +43     
+ Misses       2426     2397      -29     
Files with missing lines Coverage Δ
...es/PostgresNIO/Connection/PostgresConnection.swift 82.63% <100.00%> (-0.04%) ⬇️
.../Connection State Machine/ListenStateMachine.swift 73.88% <100.00%> (+8.20%) ⬆️
...urces/PostgresNIO/New/PostgresChannelHandler.swift 91.99% <100.00%> (+1.27%) ⬆️
Sources/PostgresNIO/New/NotificationListener.swift 87.05% <75.00%> (+1.34%) ⬆️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver-patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants